package com.studerb.tests.dao;

import java.util.List;
import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;

import com.studerb.dao.NewsGroupDao;
import com.studerb.model.NewsGroup;

public final class TestNewsGroupDao extends AbstractTransactionalDataSourceSpringContextTests {

	protected NewsGroupDao newsGroupDao;

	protected String[] getConfigLocations() {
		return new String[] { "applicationContext.xml" };
	}

	public void setNewsGroupDao(NewsGroupDao newsGroupDao) {
		this.newsGroupDao = newsGroupDao;
	}

	public void testCreate() {
		try {
			deleteFromTables(new String[] { "NewsGroup" });
			NewsGroup newsGroup = new NewsGroup("alt.bin.test", 1288, 2, 1289, true);
			Long id = newsGroupDao.create(newsGroup);
			assertNotNull(id);
		} catch (Exception e) {
			logger.error(e.getMessage());
			fail("Should not have caught exception");
		}
	}

	public void testRead() {
		try {
			NewsGroup newsGroup = new NewsGroup("alt.bin.test", 1288, 2, 1289, true);
			Long id = newsGroupDao.create(newsGroup);
			assertNotNull(id);
			newsGroupDao.flush();
			newsGroupDao.clear();
			NewsGroup sameNewsGroup = newsGroupDao.read(id);
			assertEquals(newsGroup, sameNewsGroup);
		} catch (Exception e) {
			logger.error(e.getMessage());
			fail("Should not have caught exception");
		}
	}

	public void testUpdate() {
		try {
			NewsGroup newsGroup = new NewsGroup("alt.bin.test", 1288, 2, 1289, true);
			Long id = newsGroupDao.create(newsGroup);
			assertNotNull(id);
			newsGroup.setGroupName("alt.some.other.host");
			NewsGroup newNewsGroup = newsGroupDao.read(id);
			assertNotNull(newNewsGroup);
			assertEquals("alt.some.other.host", newNewsGroup.getGroupName());
		} catch (Exception e) {
			logger.error(e.getMessage());
			fail("Should not have caught exception");
		}
	}

	public void testDelete() {
		try {
			NewsGroup newsGroup = new NewsGroup("alt.bin.test", 700, 1, 700, true);
			Long id = newsGroupDao.create(newsGroup);
			assertNotNull(id);
			newsGroupDao.delete(newsGroup);
			newsGroupDao.flush();
			newsGroupDao.clear();
			NewsGroup newNewsGroup = newsGroupDao.read(id);
			assertNull(newNewsGroup);
		} catch (Exception e) {
			logger.error(e.getMessage());
			fail("Should not have caught exception");
		}
	}

	public void testDeleteAll() {
		try {
			deleteFromTables(new String[] { "NewsGroup" });
			NewsGroup newsGroup1 = new NewsGroup("alt.bin.test", 700, 1, 700, true);
			NewsGroup newsGroup2 = new NewsGroup("alt.bin.someother", 200, 1, 200, false);
			NewsGroup newsGroup3 = new NewsGroup("alt.bin.thethire", 102, 1, 102, false);
			Long id1 = newsGroupDao.create(newsGroup1);
			Long id2 = newsGroupDao.create(newsGroup2);
			Long id3 = newsGroupDao.create(newsGroup3);
			newsGroupDao.flush();
			newsGroupDao.clear();
			int count = newsGroupDao.getCount();
			assertTrue(count >= 3);
			assertNotNull(id1);
			assertNotNull(id2);
			assertNotNull(id3);
			newsGroupDao.flush();
			newsGroupDao.clear();
			int deletedCount = newsGroupDao.deleteAll();
			assertTrue(deletedCount >= 3);
			newsGroupDao.flush();
			newsGroupDao.clear();
			int postCount = newsGroupDao.getCount();
			assertTrue(postCount == 0);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e.getMessage());
			fail("Should not have caught exception");
		}
	}

	public void testGetSubscribed() {
		try {
			deleteFromTables(new String[] { "NewsGroup" });
			List<NewsGroup> list = newsGroupDao.getAll();
			assertEquals(0, list.size());
			NewsGroup newsGroup1 = new NewsGroup("alt.bin.test", 700, 3, 703, true);
			NewsGroup newsGroup2 = new NewsGroup("alt.bin.someother", 200, 3, 203, false);
			NewsGroup newsGroup3 = new NewsGroup("alt.bin.thethire", 100, 5, 105, false);
			newsGroup2.setSubscribed(true);
			newsGroup3.setSubscribed(true);
			Long id1 = newsGroupDao.create(newsGroup1);
			Long id2 = newsGroupDao.create(newsGroup2);
			Long id3 = newsGroupDao.create(newsGroup3);
			newsGroupDao.flush();
			newsGroupDao.clear();
			logger.debug("id1: " + id1);
			assertNotNull(id1);
			logger.debug("id2: " + id2);
			assertNotNull(id1);
			logger.debug("id3: " + id3);
			List<NewsGroup> subscribed = newsGroupDao.getSubscribed();
			assertTrue(subscribed.size() == 2);
			assertTrue(subscribed.contains(newsGroup2));
			assertTrue(subscribed.contains(newsGroup3));
			assertTrue(!subscribed.contains(newsGroup1));
		} catch (Exception e) {
			logger.error(e.getMessage());
			fail("Should not have caught exception");
		}
	}

	public void testFindByOrder() {
		deleteFromTables(new String[] { "NewsGroup" });
		NewsGroup newsGroup1 = new NewsGroup("alt.bin.a", 500, 50, 550, true);
		NewsGroup newsGroup2 = new NewsGroup("alt.bin.m", 72, 72, 144, false);
		NewsGroup newsGroup3 = new NewsGroup("alt.bin.z", 105, 5, 110, false);
		Long id1 = newsGroupDao.create(newsGroup1);
		Long id2 = newsGroupDao.create(newsGroup2);
		Long id3 = newsGroupDao.create(newsGroup3);
		assertNotNull(id1);
		assertNotNull(id2);
		assertNotNull(id3);
		newsGroupDao.flush();
		newsGroupDao.clear();
		List<NewsGroup> groupsByNameAsc = newsGroupDao.getAllByOrder("name", "asc");
		assertTrue(groupsByNameAsc.get(0).getGroupName().equals("alt.bin.a"));
		assertTrue(groupsByNameAsc.get(1).getGroupName().equals("alt.bin.m"));
		assertTrue(groupsByNameAsc.get(2).getGroupName().equals("alt.bin.z"));

		List<NewsGroup> groupsByNameDesc = newsGroupDao.getAllByOrder("name", "desc");
		assertTrue(groupsByNameDesc.get(0).getGroupName().equals("alt.bin.z"));
		assertTrue(groupsByNameDesc.get(1).getGroupName().equals("alt.bin.m"));
		assertTrue(groupsByNameDesc.get(2).getGroupName().equals("alt.bin.a"));
	}

	public void testSubscribed() {
		try {
			deleteFromTables(new String[] { "NewsGroup" });
			NewsGroup newsGroup1 = new NewsGroup("alt.bin.a",700,1, 700, true);
			newsGroup1.setSubscribed(true);
			NewsGroup newsGroup2 = new NewsGroup("alt.bin.m",500, 1, 500, false);
			newsGroup2.setSubscribed(true);
			NewsGroup newsGroup3 = new NewsGroup("alt.bin.z", 102, 1, 102, false);
			newsGroup3.setSubscribed(false);
			Long id1 = newsGroupDao.create(newsGroup1);
			Long id2 = newsGroupDao.create(newsGroup2);
			Long id3 = newsGroupDao.create(newsGroup3);
			assertNotNull(id1);
			assertNotNull(id2);
			assertNotNull(id3);
			newsGroupDao.flush();
			newsGroupDao.clear();
			List<NewsGroup> subscribed = newsGroupDao.getSubscribed();
			List<NewsGroup> unSubscribed = newsGroupDao.getUnSubscribed();
			assertTrue(subscribed.size() == 2);
			assertTrue(unSubscribed.size() == 1);
			int deletedSub = newsGroupDao.deleteSubscribed();
			int deletedUnSub = newsGroupDao.deleteUnSubscribed();
			assertTrue(deletedSub == 2);
			assertTrue(deletedUnSub == 1);
		} catch (Exception e) {
			fail("Should not have caught exception: " + e.getMessage());
		}

	}

}
